﻿
#region Using

using GalaSoft.MvvmLight.Command;
using Rio.Manager.Application.ViewModel.BaseClass;
using Rio.Framework.Localisation;
using System;
using System.Collections.ObjectModel;
using Rio.Applications.Web.Services;
using System.ServiceModel.DomainServices.Client;
using System.Windows;

using Rio.Manager.Application.ViewModel.Locator;
using Rio.Framework.Pages.Helpers;
using Rio.Framework.Pages.Context;
using NetBay.Core.BusinessEntities;
using Rio.Framework.Pages.AppCode.Enums;
using System.Windows.Data;
using System.Linq;
using Rio.Framework.Pages;
using Rio.Manager.Application.Model;
using System.Collections.Generic;
using Rio.Applications.Web.Services.AD;
using NetBay.Core.BusinessEntities.ActiveDirectory;
using NetBay.Core.BusinessEntities.ActiveDirectory.Objects;
using NetBay.Core.Silverlight.Tools;
using GalaSoft.MvvmLight.Messaging;
using NetBay.Core.Silverlight.Log;

#endregion Using

namespace Rio.Manager.Application.ViewModel.Administration
{
	public class GroupAssociationTabViewModel : TabViewModelBase
	{
		#region Fields

		private AdDomainContext _oAdDomainContext;
		private AdDomainContext _oAdDomainContextToMap;

		public RelayCommand InitializationCommand { get; set; }
		public RelayCommand AssociationAddCommand { get; set; }
		public RelayCommand AssociationAddAllCommand { get; set; }
		public RelayCommand AssociationDeleteCommand { get; set; }
		public RelayCommand AssociationDeleteAllCommand { get; set; }
		public RelayCommand SaveAssociationCommand { get; set; }
		public RelayCommand CancelAssociationCommand { get; set; }
		public RelayCommand CloseAssociationCommand { get; set; }

		private string _LblGroupAssociationExplanation;

		private string _LblOrganization;

		private ObservableCollection<Organization> _oLstOrganization;

		private Organization _SelectedGroupOrganization;

		private string _LblConfiAd;

		private ObservableCollection<AdStructureItem> _AdConfigCustomer;

		private AdStructureItem _SelectedAdConfigCustomer;

		private string _LblGridGroupRioTitle;

		private string _LblGridRioAssociationADTitle;

		private string _LblGridADTitle;

		private string _rdbUserAdLabel;

		private Boolean _rdbUserAdIsChecked;

		private string _rdbGroupAdLabel;

		private Boolean _rdbGroupAdIsChecked;

		private ObservableCollection<Group> _OrganizationRioGroupList;

		private ObservableCollection<Group> _SelectedOrganizationRioGroup;

		private string _HeaderGroupName;

		private string _HeaderGroupType;

		private ObservableCollection<AdObject> _AdObjectMappedList;

		private ObservableCollection<AdObject> _SelectedAdObjectMapped;

		private ObservableCollection<AdObject> _AdObjectToMappedList;

		private ObservableCollection<AdObject> _SelectedAdObjectToMapped;

		private string _BtnSave;

		private string _BtnCancelModification;

		private string _BtnClose;

		private Boolean _CanSelectOrganization;

		private Boolean _CanSelectAdConfig;

		private Boolean _CanAddAdItemToGroupRio;

		private Boolean _CanAddAllAdItemToGroupRio;

		private Boolean _CanDeleteGroupRioItem;

		private Boolean _CanDeleteAllGroupRioItem;

		private Boolean _CanSaveModification;

		private Boolean _CanCancelModification;

        private Boolean _CanClose;
				
		#endregion Fields

		#region Properties

		public AdDomainContext GetAdContext
		{
			get
			{
				if (_oAdDomainContext == null)
					_oAdDomainContext = new AdDomainContext();

				return _oAdDomainContext;
			}
		}

		public AdDomainContext GetAdContextToMap
		{
			get
			{
				if (_oAdDomainContextToMap == null)
					_oAdDomainContextToMap = new AdDomainContext();

				return _oAdDomainContextToMap;
			}
		}

		public string LblGroupAssociationExplanation
		{
			get
			{
				return _LblGroupAssociationExplanation;
			}
			set
			{
				_LblGroupAssociationExplanation = value;
				RaisePropertyChanged("LblGroupAssociationExplanation");
			}
		}

		public string LblOrganization
		{
			get
			{
				return _LblOrganization;
			}
			set
			{
				_LblOrganization = value;
				RaisePropertyChanged("LblOrganization");
			}
		}

		public ObservableCollection<Organization> LstOrganization
		{
			get
			{
				return _oLstOrganization;
			}
			set
			{
				_oLstOrganization = value;
				RaisePropertyChanged("LstOrganization");
			}
		}

		public Organization SelectedGroupOrganization
		{
			get
			{
				return _SelectedGroupOrganization;
			}
			set
			{
				_SelectedGroupOrganization = value;
				RaisePropertyChanged("SelectedGroupOrganization");

				//Fill organization rio group. 
				if (SelectedGroupOrganization != null)
				{
					FillRioGroupByOrganizationSelected(SelectedGroupOrganization.Identifier);
				}
			}
		}

		public string LblConfiAd
		{
			get
			{
				return _LblConfiAd;
			}
			set
			{
				_LblConfiAd = value;
				RaisePropertyChanged("LblConfiAd");
			}
		}

		public ObservableCollection<AdStructureItem> AdConfigCustomer
		{
			get
			{
				return _AdConfigCustomer;
			}
			set
			{
				_AdConfigCustomer = value;
				RaisePropertyChanged("AdConfigCustomer");
			}
		}

		public AdStructureItem SelectedAdConfigCustomer
		{
			get
			{
				return this._SelectedAdConfigCustomer;
			}
			set
			{
				this._SelectedAdConfigCustomer = value;
				this.RaisePropertyChanged("SelectedAdConfigCustomer");

				if (SelectedAdConfigCustomer != null)
				{
					//Initialize properties.
					AdObjectToMappedList = new ObservableCollection<AdObject>();
					SelectedAdObjectToMapped = null;

					//Fill Ad information list
                    FillCustomerADColumn(SelectedAdConfigCustomer);
				}
			}
		}

		public string LblGridGroupRioTitle
		{
			get
			{
				return _LblGridGroupRioTitle;
			}
			set
			{
				_LblGridGroupRioTitle = value;
				RaisePropertyChanged("LblGridGroupRioTitle");
			}
		}

		public string LblGridRioAssociationADTitle
		{
			get
			{
				return _LblGridRioAssociationADTitle;
			}
			set
			{
				_LblGridRioAssociationADTitle = value;
				RaisePropertyChanged("LblGridRioAssociationADTitle");
			}
		}

		public string LblGridADTitle
		{
			get
			{
				return _LblGridADTitle;
			}
			set
			{
				_LblGridADTitle = value;
				RaisePropertyChanged("LblGridADTitle");
			}
		}

		public string rdbUserAdLabel
		{
			get
			{
				return _rdbUserAdLabel;
			}
			set
			{
				_rdbUserAdLabel = value;
				RaisePropertyChanged("rdbUserAdLabel");
			}
		}

		public Boolean rdbUserAdIsChecked
		{
			get
			{
				return _rdbUserAdIsChecked;
			}
			set
			{
				_rdbUserAdIsChecked = value;
				RaisePropertyChanged("rdbUserAdIsChecked");

				//Label Information Ad change and retrieves Ad informations.
				if (rdbUserAdIsChecked)
				{
					//Change label.
					LblGridADTitle = string.Format(Resx.GetLabel(ResxRioManagerGroup.GROUP_ASSOCIATION_AD_GROUP_TITLE), Resx.GetLabel(ResxRioManagerGroup.GROUP_ASSOCIATION_USER));

					//Fill Ad information list
					if (SelectedAdConfigCustomer != null)
					{
                        FillCustomerADColumn(SelectedAdConfigCustomer);
					}  
				}
			}
		}

		public string rdbGroupAdLabel
		{
			get
			{
				return _rdbGroupAdLabel;
			}
			set
			{
				_rdbGroupAdLabel = value;
				RaisePropertyChanged("rdbGroupAdLabel");
			}
		}

		public Boolean rdbGroupAdIsChecked
		{
			get
			{
				return _rdbGroupAdIsChecked;
			}
			set
			{
				_rdbGroupAdIsChecked = value;
				RaisePropertyChanged("rdbGroupAdIsChecked");

				//Label Information Ad change and retrieves Ad informations.
				if (rdbGroupAdIsChecked)
				{
					//Change label.
					LblGridADTitle = string.Format(Resx.GetLabel(ResxRioManagerGroup.GROUP_ASSOCIATION_AD_GROUP_TITLE), Resx.GetLabel(ResxRioManagerGroup.GROUP_ASSOCIATION_GROUP));

					//Fill Ad information list
					if (SelectedAdConfigCustomer != null)
					{
                        FillCustomerADColumn(SelectedAdConfigCustomer);
					}                    
				}
			}
		}

		public ObservableCollection<Group> OrganizationRioGroupList
		{
			get
			{
				return _OrganizationRioGroupList;
			}
			set
			{
				_OrganizationRioGroupList = value;
				RaisePropertyChanged("OrganizationRioGroupList");
			}
		}

		public ObservableCollection<Group> SelectedOrganizationRioGroup
		{
			get
			{
				return _SelectedOrganizationRioGroup;
			}
			set
			{
				_SelectedOrganizationRioGroup = value;
				RaisePropertyChanged("SelectedOrganizationRioGroup");

				//Fill organization rio group.                
				FillMappedByRioGroupSelected();
			}
		}

		public string HeaderGroupName
		{
			get
			{
				return _HeaderGroupName;
			}
			set
			{
				_HeaderGroupName = value;
				RaisePropertyChanged("HeaderGroupName");
			}
		}

		public string HeaderGroupType
		{
			get
			{
				return _HeaderGroupType;
			}
			set
			{
				_HeaderGroupType = value;
				RaisePropertyChanged("HeaderGroupType");
			}
		}

		public ObservableCollection<AdObject> AdObjectMappedList
		{
			get
			{
				return _AdObjectMappedList;
			}
			set
			{
				_AdObjectMappedList = value;
				RaisePropertyChanged("AdObjectMappedList");
			}
		}

		public ObservableCollection<AdObject> SelectedAdObjectMapped
		{
			get
			{
				return _SelectedAdObjectMapped;
			}
			set
			{
				_SelectedAdObjectMapped = value;
				RaisePropertyChanged("SelectedAdObjectMapped");

				//Check buttons Status "Add".
                CheckButtonAddAndDeleteStatus("Delete");
			}
		}

		public ObservableCollection<AdObject> AdObjectToMappedList
		{
			get
			{
				return _AdObjectToMappedList;
			}
			set
			{
				_AdObjectToMappedList = value;
				RaisePropertyChanged("AdObjectToMappedList");
			}
		}

		public ObservableCollection<AdObject> SelectedAdObjectToMapped
		{
			get
			{
				return _SelectedAdObjectToMapped;
			}
			set
			{
				_SelectedAdObjectToMapped = value;
				RaisePropertyChanged("SelectedAdObjectToMapped");

				//Check buttons status "Delete".
                CheckButtonAddAndDeleteStatus("Add");
			}
		}

		public string BtnSave
		{
			get
			{
				return _BtnSave;
			}
			set
			{
				_BtnSave = value;
				RaisePropertyChanged("BtnSave");
			}
		}

		public string BtnCancelModification
		{
			get
			{
				return _BtnCancelModification;
			}
			set
			{
				_BtnCancelModification = value;
				RaisePropertyChanged("BtnCancelModification");
			}
		}

		public string BtnClose
		{
			get
			{
				return _BtnClose;
			}
			set
			{
				_BtnClose = value;
				RaisePropertyChanged("BtnClose");
			}
		}

		public Boolean CanSelectOrganization
		{
			get
			{
				return _CanSelectOrganization;
			}
			set
			{
				_CanSelectOrganization = value;
				RaisePropertyChanged("CanSelectOrganization");
			}
		}

		public Boolean CanSelectAdConfig
		{
			get
			{
				return _CanSelectAdConfig;
			}
			set
			{
				_CanSelectAdConfig = value;
				RaisePropertyChanged("CanSelectAdConfig");
			}
		}

		public Boolean CanAddAdItemToGroupRio
		{
			get
			{
				return _CanAddAdItemToGroupRio;
			}
			set
			{
				_CanAddAdItemToGroupRio = value;
				RaisePropertyChanged("CanAddAdItemToGroupRio");                
			}
		}

		public Boolean CanAddAllAdItemToGroupRio
		{
			get
			{
				return _CanAddAllAdItemToGroupRio;
			}
			set
			{
				_CanAddAllAdItemToGroupRio = value;
				RaisePropertyChanged("CanAddAllAdItemToGroupRio");
			}
		}

		public Boolean CanDeleteGroupRioItem
		{
			get
			{
				return _CanDeleteGroupRioItem;
			}
			set
			{
				_CanDeleteGroupRioItem = value;
				RaisePropertyChanged("CanDeleteGroupRioItem");
			}
		}

		public Boolean CanDeleteAllGroupRioItem
		{
			get
			{
				return _CanDeleteAllGroupRioItem;
			}
			set
			{
				_CanDeleteAllGroupRioItem = value;
				RaisePropertyChanged("CanDeleteAllGroupRioItem");
			}
		}

		public Boolean CanSaveModification
		{
			get
			{
				return _CanSaveModification;
			}
			set
			{
				_CanSaveModification = value;
				RaisePropertyChanged("CanSaveModification");
			}
		}

		public Boolean CanCancelModification
		{
			get
			{
				return _CanCancelModification;
			}
			set
			{
				_CanCancelModification = value;
				RaisePropertyChanged("CanCancelModification");
			}
		}

        public Boolean CanClose
        {
            get
            {
                return _CanClose;
            }
            set
            {
                _CanClose = value;
                RaisePropertyChanged("CanClose");
            }
        }

		#endregion Properties

		#region Constructor and Initialization

		public GroupAssociationTabViewModel()
			: base()
		{
			CanCloseTab = true;

			//Icon.
			TabIcon = new Uri("/Rio.Manager.Application;component/Assets/Images/Group_Link_Rio and_AD.png", UriKind.Relative);    
		}

		/// <summary>Inits the commands.</summary>
		public override void InitCommands()
		{
			InitializationCommand = new RelayCommand(Initialization);
			AssociationAddCommand = new RelayCommand(AddAdAssociationInRIOGroup); 
			AssociationAddAllCommand = new RelayCommand(AddAllAdAssociationInRIOGroup); 
			AssociationDeleteCommand = new RelayCommand(DeleteAdAssociationInRIOGroup);
			AssociationDeleteAllCommand = new RelayCommand(DeleteAllAdAssociationInRIOGroup);
			SaveAssociationCommand = new RelayCommand(SaveAssociation);
			CancelAssociationCommand = new RelayCommand(CancelAssociation);
			CloseAssociationCommand = new RelayCommand(CloseAssociation);
		}

		/// <summary>Initializations this instance.</summary>
		private void Initialization()
		{            
			InitLabels();
			InitProperties();
			FillOrganization();
			FillAdConfiguration();
		}

		/// <summary>Inits the labels.</summary>
		public override void InitLabels()
		{
			//Retrieves the labels. 
			TabTitle = Resx.GetLabel(ResxRioManagerGroup.GROUP_ASSOCIATION);

			//Label.
			LblGroupAssociationExplanation = Resx.GetLabel(ResxRioManagerGroup.GROUP_ASSOCIATION_EXPLANATION);
			LblOrganization = Resx.GetLabel(ResxRioManagerGroup.GROUP_ASSOCIATION_ORGANIZATION);
			LblConfiAd = Resx.GetLabel(ResxRioManagerGroup.GROUP_AD_CONFIG); 
			LblGridGroupRioTitle = Resx.GetLabel(ResxRioManagerGroup.GROUP_ASSOCIATION_RIO_GROUP_TITLE);
			LblGridRioAssociationADTitle = Resx.GetLabel(ResxRioManagerGroup.GROUP_ASSOCIATION_RIO_AND_AD_GROUP_TITLE);
			LblGridADTitle = Resx.GetLabel(ResxRioManagerGroup.GROUP_ASSOCIATION_AD_GROUP_TITLE);
			rdbUserAdLabel = Resx.GetLabel(ResxRioManagerGroup.GROUP_ASSOCIATION_USER);
			rdbGroupAdLabel = Resx.GetLabel(ResxRioManagerGroup.GROUP_ASSOCIATION_GROUP);
			HeaderGroupName = Resx.GetLabel(ResxRioManagerGroup.GROUP_ASSOCIATION_HEADER_GROUP_NAME);
			HeaderGroupType = Resx.GetLabel(ResxRioManagerGroup.GROUP_ASSOCIATION_HEADER_GROUP_TYPE);
			
			////Buttons.           
			BtnSave = Resx.GetLabel(ResxRioManagerGroup.GROUP_ASSOCIATION_BTN_SAVE);
			BtnCancelModification = Resx.GetLabel(ResxRioManagerGroup.GROUP_ASSOCIATION_BTN_CANCEL);
			BtnClose = Resx.GetLabel(ResxRioManagerGroup.GROUP_ASSOCIATION_BTN_CLOSE);
		}

		/// <summary>Inits the properties.</summary>
		public void InitProperties()
		{
            //Log.
            Logger.Write("GroupAssociationTabViewModel.InitProperties (No parameters)...", Logger.Level.Debug);

			//Group Ad radio button is check by default.
			rdbGroupAdIsChecked = true;

			//Initialize properties organization combox box.
			LstOrganization = new ObservableCollection<Organization>();
			CanSelectOrganization = true;
			SelectedGroupOrganization = null;

			//Initialize Ad configuration combo box.
			AdConfigCustomer = new ObservableCollection<AdStructureItem>();
			CanSelectAdConfig = true;
			SelectedAdConfigCustomer = null;

			//Initialize RIO group grid.
			OrganizationRioGroupList = new ObservableCollection<Group>();
			SelectedOrganizationRioGroup = null;

			//Initialize RIO mapped grid.
			AdObjectMappedList = new ObservableCollection<AdObject>();
			SelectedAdObjectMapped = null;

			//Initialize Ad grid.
			AdObjectToMappedList = new ObservableCollection<AdObject>();
			SelectedAdObjectToMapped = null;

			//Initialize buttons.
			InitializeButtons(false);
		}

		/// <summary>Set the buttons status</summary>
		/// <param name="p_bButtonsStatus"></param>
		public void InitializeButtons(Boolean p_bButtonsStatus)
		{
            //Log.
            Logger.Write("GroupAssociationTabViewModel.InitializeButtons (p_bButtonsStatus <" + p_bButtonsStatus.ToString() + ">)...", Logger.Level.Debug);

            //Change Status Buttons.
			CanAddAdItemToGroupRio = p_bButtonsStatus;
			CanAddAllAdItemToGroupRio = p_bButtonsStatus;
			CanDeleteGroupRioItem = p_bButtonsStatus;
			CanDeleteAllGroupRioItem = p_bButtonsStatus;
			CanSaveModification = p_bButtonsStatus;
			CanCancelModification = p_bButtonsStatus;
            
            //Button Close.
            CanClose = true;
            if ((SelectedOrganizationRioGroup != null) && (SelectedOrganizationRioGroup.Count != 0))
            {
                CanClose = false;
            }
		}

		/// <summary>Load RIO Organization.</summary>
		public void FillOrganization()
		{
            //Log.
            Logger.Write("GroupAssociationTabViewModel.FillOrganization (No parameters)...", Logger.Level.Debug);

			//Retrieves all the RIO Organization.           
			BusinessEntitiesDomainContext l_oBEDomainContext = new BusinessEntitiesDomainContext();
			var query = l_oBEDomainContext.GetAllRioOrganizationQuery();
			l_oBEDomainContext.Load(query, OnGetAllRioOrganizationCallback, null);
		}

		/// <summary>Fill Ad Configuration.</summary>
		public void FillAdConfiguration()
		{
            //Log.
            Logger.Write("GroupAssociationTabViewModel.FillAdConfiguration (No parameters)...", Logger.Level.Debug);

			//Load all customer configuration Ad.
			var query = GetAdContext.GetAdConfigListQuery();
			GetAdContext.Load(query, OnGetAdConfigListQueryCallback, null);
		}

        /// <summary>Retrieves Ad Name Mapped.</summary>
        public void RetrievesAdNameMapped()
        {
            //Log.
            Logger.Write("GroupAssociationTabViewModel.RetrievesAdNameMapped (No parameters)...", Logger.Level.Debug);

            GetAdContext.GetAdNameMapped(result =>
            {
                if (result.HasError)
                {
                    //Log Error.
                    Logger.Write("GroupSynchronizationTabViewModel.RetrievesAdNameMapped Exception [" + result.Error.Message + "]", Logger.Level.Error);

                    //User error message.
                    MessageBoxChildWindow L_oMessage = new MessageBoxChildWindow(Resx.GetLabel(ResxCommon.ERROR), Resx.GetLabel(ResxRioManagerGroup.GROUP_MSG_ASSOCIATION_AD_NAME_MAPPED_ERROR), MessageBoxButtons.Ok, MessageBoxIcon.Error);
                    L_oMessage.Show();
                }
                else
                {
                    //Set Ad Column name selected and remove other. (It does not support multiple active directory)
                    if (AdConfigCustomer.Any(f => f.AdName.Contains(result.Value)))
                    {
                        AdConfigCustomer.ToList().ForEach(f => {if (f.AdName != result.Value) AdConfigCustomer.Remove(f);});
                        SelectedAdConfigCustomer = AdConfigCustomer.Where(f => f.AdName == result.Value).First();
                    }
                }

                //Busy indicator.
                BusyIndicator.RemoveBusyTask();

            },
                null);    
        }

		#endregion Constructor and Initialization

		#region Methods

		/// <summary>
		/// Retrieves all the organization RIO Group.
		/// </summary>
		public void FillRioGroupByOrganizationSelected(long p_lOrganizationId)
		{
            //Log.
            Logger.Write("GroupAssociationTabViewModel.FillRioGroupByOrganizationSelected (p_lOrganizationId <" + p_lOrganizationId.ToString() + ">)...", Logger.Level.Debug);

			//Retrieves all the RIO Organization.          
			BusinessEntitiesDomainContext l_oBEDomainContext = new BusinessEntitiesDomainContext();
			var query = l_oBEDomainContext.GetAllGroupRioByOrganizationQuery(p_lOrganizationId);
			l_oBEDomainContext.Load(query, OnGetAllRioOrganizationGroupCallback, null); 
		}

		/// <summary>
		/// Retrieves all Ad information enabled to mapped RIO group.
		/// </summary>
        public void FillCustomerADColumn(AdStructureItem p_oAdStructure)
		{
            try
            {
                //Log.
                Logger.Write("GroupAssociationTabViewModel.FillCustomerADColumn (p_oAdStructure <" + p_oAdStructure.AdName + ">)...", Logger.Level.Debug);

                //Busy indicator.
                BusyIndicator.Clear();
                BusyIndicator.AddBusyTask();

                //Serialization adStructure Object.
                string l_sSerializableAdStructureSelected = SerializationHelper.Serialize<AdStructureItem>(p_oAdStructure);

                //Initialize Ad grid.
                AdObjectToMappedList = new ObservableCollection<AdObject>();
                SelectedAdObjectToMapped = null;

                //Clear Ad Information List.
                if (GetAdContextToMap.AdObjects.Count != 0)
                {
                    GetAdContextToMap.AdObjects.Clear();
                }

                //Retrieves all Ad information list enabled to mapped RIO group according to user choice.
                if (rdbGroupAdIsChecked)
                {
                    var query = GetAdContextToMap.GetAdGroupListQuery(l_sSerializableAdStructureSelected);
                    GetAdContextToMap.Load(query, OnGetAdGroupListCallback, true);
                }
                else if (rdbUserAdIsChecked)
                {
                    var query = GetAdContextToMap.GetAdUserListQuery(l_sSerializableAdStructureSelected);
                    GetAdContextToMap.Load(query, OnGetAdUserListCallback, null);
                }
            }
            catch (Exception ex)
            {
                //Log Error.
                Logger.Write("GroupAssociationTabViewModel.FillCustomerADColumn Exception [" + ex.Message + "]", Logger.Level.Error);

                //Busy indicator.
                BusyIndicator.RemoveBusyTask();
            }            
		}

		/// <summary>
		/// Retrieves all RIO Group mapped information mapped.
		/// </summary>
		public void FillMappedByRioGroupSelected()
		{                        
            //Log.
            Logger.Write("GroupAssociationTabViewModel.FillMappedByRioGroupSelected (No parameters)...", Logger.Level.Debug);

            //Initialize navigation buttons.
            InitializeButtons(false);

			//Initialize the rio group mapped grid.
			AdObjectMappedList = new ObservableCollection<AdObject>();
			SelectedAdObjectMapped = null;

            //Reject changes made.
            GetAdContext.RejectChanges();

			//Clear Rio Group Mapped Information List.
			if (GetAdContext.AdObjects.Count != 0)
			{
                GetAdContext.AdObjects.Clear();
			}
			
			//Fill organization rio group. 
			if ((SelectedOrganizationRioGroup != null) && (SelectedOrganizationRioGroup.Count != 0))
			{
				//Retrieves RIO Group selected mapped information list.
				var query = GetAdContext.GetAdMappedObjectQuery(SelectedOrganizationRioGroup[0].Identifier, AdObjectType.All);
				GetAdContext.Load(query, OnGetAdMappedObjectListQueryCallback, null);
			}
		}

		/// <summary>Clones RIO Group Mapped.</summary>
		/// <param name="p_oRioGroupInformationMapped">Object Information rio group mapped.</param>
		/// <returns></returns>
		public ObservableCollection<AdObject> CloneRioGroupMappedInformation(ObservableCollection<AdObject> p_oRioGroupInformationMapped)
		{
            //Log.
            Logger.Write("GroupAssociationTabViewModel.CloneRioGroupMappedInformation (p_oRioGroupInformationMapped <" + p_oRioGroupInformationMapped.ToString() + ">)...", Logger.Level.Debug);

			//Variable initialization.
			ObservableCollection<AdObject> l_oReturnClone = new ObservableCollection<AdObject>();

			//Build the clone.
			foreach (AdObject l_oRioGroupInformationMappedItem in p_oRioGroupInformationMapped)
			{
				if (l_oRioGroupInformationMappedItem is AdGroup)
				{
					AdGroup l_oRioGroupInformationMappedGroupItem = new AdGroup();

					l_oRioGroupInformationMappedGroupItem.Enable = ((AdGroup)l_oRioGroupInformationMappedItem).Enable;
					l_oRioGroupInformationMappedGroupItem.Name = ((AdGroup)l_oRioGroupInformationMappedItem).Name;
					l_oRioGroupInformationMappedGroupItem.GuidOfAdObject = ((AdGroup)l_oRioGroupInformationMappedItem).GuidOfAdObject;
					l_oRioGroupInformationMappedGroupItem.TypeOfAdObject = ((AdGroup)l_oRioGroupInformationMappedItem).TypeOfAdObject;

					l_oReturnClone.Add(l_oRioGroupInformationMappedGroupItem);
				}
				else if (l_oRioGroupInformationMappedItem is AdUser)
				{
					AdUser l_oRioGroupInformationMappedUserItem = new AdUser();

					l_oRioGroupInformationMappedUserItem.Enable = ((AdUser)l_oRioGroupInformationMappedItem).Enable;
					l_oRioGroupInformationMappedUserItem.Login = ((AdUser)l_oRioGroupInformationMappedItem).Login;
					l_oRioGroupInformationMappedUserItem.Name = ((AdUser)l_oRioGroupInformationMappedItem).Name;
					l_oRioGroupInformationMappedUserItem.FirstName = ((AdUser)l_oRioGroupInformationMappedItem).FirstName;
					l_oRioGroupInformationMappedUserItem.Email = ((AdUser)l_oRioGroupInformationMappedItem).Email;
					l_oRioGroupInformationMappedUserItem.GuidOfAdObject = ((AdUser)l_oRioGroupInformationMappedItem).GuidOfAdObject;
					l_oRioGroupInformationMappedUserItem.TypeOfAdObject = ((AdUser)l_oRioGroupInformationMappedItem).TypeOfAdObject;

					l_oReturnClone.Add(l_oRioGroupInformationMappedUserItem);
				}              
			}

			//Return Value.
			return l_oReturnClone;		
		}

		/// <summary>Check if buttons are or arent't enabled.</summary>
		/// <param name="p_sAction">Button action to check</param>
		public void CheckButtonAddAndDeleteStatus(string p_sAction)
		{
            //Log.
            Logger.Write("GroupAssociationTabViewModel.CheckButtonAddAndDeleteStatus (p_sAction <" + p_sAction + ">)...", Logger.Level.Debug);

			switch (p_sAction.ToLower())
			{
				case "add":
					CanAddAdItemToGroupRio = false;
					CanAddAllAdItemToGroupRio = false;
					if ((SelectedAdObjectToMapped != null) && (SelectedAdObjectToMapped.Count != 0))
					{
						if (SelectedAdObjectToMapped.Count == AdObjectToMappedList.Count)
						{
							CanAddAllAdItemToGroupRio = true;
						}
						else
						{
							CanAddAdItemToGroupRio = true;                       
						}
					}                    
					break;

				case "delete":
					CanDeleteAllGroupRioItem = false;
					CanDeleteGroupRioItem = false;
					if ((SelectedAdObjectMapped != null) && (SelectedAdObjectMapped.Count != 0))
					{
						if (SelectedAdObjectMapped.Count == AdObjectMappedList.Count)
						{
							CanDeleteAllGroupRioItem = true;
						}
						else
						{
							CanDeleteGroupRioItem = true;                       
						}
					}            
					break;

				default:
                    //Log Error. --> Exception to implemented.

                    Logger.Write("GroupAssociationTabViewModel.CheckButtonAddAndDeleteStatus: The " + p_sAction + " Action isn't implemented.", Logger.Level.Error);
					throw new NotImplementedException();

					break;
			}
		}

		/// <summary>Add selected Ad information list to Rio group.</summary>
		public void AddAdInformationToRioGroupMappedList()
		{
            //Log.
            Logger.Write("GroupAssociationTabViewModel.AddAdInformationToRioGroupMappedList (No parameters)...", Logger.Level.Debug);

			//Build new SelectedAdObjectToMapped.
			ObservableCollection<AdObject> l_oSelectedAdObjectToMapped = CloneRioGroupMappedInformation(SelectedAdObjectToMapped);

			//Set the object group identifier, add items to list and Ad Name.
			foreach (AdObject l_oAdObjectToMapItem in l_oSelectedAdObjectToMapped)
			{
                //Test to see if Object existe.
                if (AdObjectMappedList.Where(p => p.GuidOfAdObject == l_oAdObjectToMapItem.GuidOfAdObject).FirstOrDefault() == null)
                {
                    l_oAdObjectToMapItem.DisplayName = l_oAdObjectToMapItem is AdGroup ? ((AdGroup)l_oAdObjectToMapItem).Name : String.Format("{0} {1}", ((AdUser)l_oAdObjectToMapItem).FirstName, ((AdUser)l_oAdObjectToMapItem).Name);
                    l_oAdObjectToMapItem.MappedGroupIdentifier = SelectedOrganizationRioGroup[0].Identifier;
                    l_oAdObjectToMapItem.AdName = SelectedAdConfigCustomer.AdName;
                    l_oAdObjectToMapItem.KeyId = Guid.NewGuid();
                    AdObjectMappedList.Add(l_oAdObjectToMapItem);
                    GetAdContext.AdObjects.Add(l_oAdObjectToMapItem);
                }
			}

            //Check if navigation button must to be enable or not.
            CheckButtonAddAndDeleteStatus("Delete");
		}

		/// <summary>Delete selected rio group mapped list.</summary>
		public void DeleteRioGroupMappedList()
		{
            //Log.
            Logger.Write("GroupAssociationTabViewModel.DeleteRioGroupMappedList (No parameters)...", Logger.Level.Debug);
            
			//Delete all the selected rio group mapped list.
			foreach (AdObject l_oAdObjectMappedToDelete in SelectedAdObjectMapped)
			{
				AdObjectMappedList.Remove(l_oAdObjectMappedToDelete);
				GetAdContext.AdObjects.Remove(l_oAdObjectMappedToDelete);
			}

            //Check if navigation button must to be enable or not.
            CheckButtonAddAndDeleteStatus("Delete");
		}

		#endregion Methods

        #region Button Click (command)

        /// <summary>Add Ad association in the RIO Group.</summary>
        public void AddAdAssociationInRIOGroup()
        {
            //Add Ad information selected to group rio.
            AddAdInformationToRioGroupMappedList();
        }

        /// <summary>
        /// Add all Ad association in the RIO Group.
        /// </summary>
        public void AddAllAdAssociationInRIOGroup()
        {
            //Add all Ad information to group rio.
            AddAdInformationToRioGroupMappedList();
        }

        /// <summary>
        /// Delete Ad association in the RIO Group.
        /// </summary>
        public void DeleteAdAssociationInRIOGroup()
        {
            //Delete selected rio group mapped.
            DeleteRioGroupMappedList();
        }

        /// <summary>
        /// Delete all Ad association in the RIO Group.
        /// </summary>
        public void DeleteAllAdAssociationInRIOGroup()
        {
            //Delete all rio group mapped.
            DeleteRioGroupMappedList();
        }

        /// <summary>
        /// Save the association Rio and AD tab.
        /// </summary>
        public void SaveAssociation()
        {
            //Busy indicator.
            BusyIndicator.Clear();
            BusyIndicator.AddBusyTask();

            //Save all the modification on the group Rio selected.
            GetAdContext.SubmitChanges(OnSubmitChangeCallback, null);           
        }

        /// <summary>
        /// Cancel the association Rio and AD tab.
        /// </summary>
        public void CancelAssociation()
        {
            //Reject modification change.
            GetAdContext.RejectChanges();

            //No item selected in Rio Group grid.
            Messenger.Default.Send<NotificationMessage<ObservableCollection<Group>>>(new NotificationMessage<ObservableCollection<Group>>(OrganizationRioGroupList, String.Empty));

            //Close button, Organization and Ad information choice mut to be enabled.
            CanSelectOrganization = true;
            CanSelectAdConfig = true;
            CanClose = true;
        }

        /// <summary>
        /// Close the association Rio and AD tab.
        /// </summary>
        public void CloseAssociation()
        {
            //Close the association Rio and AD tab.
            CloseTab();
        }

        #endregion Button Click (command)

		#region Callback

		/// <summary>Gets all Rio Organization.</summary>
		/// <param name="e">Rio Organization List.</param>
		private void OnGetAllRioOrganizationCallback(LoadOperation<Organization> e)
		{
			if (!e.HasError)
			{
				//Built Rio Organization list.
				SelectedOrganizationRioGroup = null;
				LstOrganization = new ObservableCollection<Organization>(e.Entities);
			}
            else
            {
                //Log Error.
                Logger.Write("GroupAssociationTabViewModel.OnGetAllRioOrganizationCallback Exception [" + e.Error.Message + "]", Logger.Level.Error);
            }
		}

		/// <summary>Gets all Ad groupe informations.</summary>
		/// <param name="e">Ad groups list.</param>
		private void OnGetAdGroupListCallback(LoadOperation<AdGroup> e)
		{
			if (!e.HasError)
			{ 
				//Fill all Ad Group Information.
				foreach (AdObject l_oOneAdGroupTemp in e.Entities)
				{
					AdObjectToMappedList.Add(l_oOneAdGroupTemp);
				}
			}
            else
            {
                //Log Error.
                Logger.Write("GroupAssociationTabViewModel.OnGetAdGroupListCallback Exception [" + e.Error.Message + "]", Logger.Level.Error);
            }

            //Busy indicator.
            BusyIndicator.RemoveBusyTask();
		}

		/// <summary>Gets all Ad user informations.</summary>
		/// <param name="e">Ad user list.</param>
		private void OnGetAdUserListCallback(LoadOperation<AdUser> e)
		{
			if (!e.HasError)
			{
				//Fill Ad User Information.
                List<AdUser> l_oAdUser = new List<AdUser>(e.Entities);
                if ((l_oAdUser.Count == 1) && (l_oAdUser[0].UserAdError))
			    {
                    //User error message.
                    MessageBoxChildWindow L_oMessage = new MessageBoxChildWindow(String.Empty, string.Format(Resx.GetLabel(ResxRioManagerGroup.GROUP_ASSOCIATION_USER_LIST_ERROR).Replace("\\n", Environment.NewLine), l_oAdUser[0].UserDisplayAdError), MessageBoxButtons.Ok, MessageBoxIcon.Error);
                    L_oMessage.Show();
			    }
			    else
			    {
                    foreach (AdObject l_oOneAdUser in l_oAdUser)
                    {
                        AdObjectToMappedList.Add(l_oOneAdUser);
                    }
			    }
			}
            else
            {
                //Log Error.
                Logger.Write("GroupAssociationTabViewModel.OnGetAdUserListCallback Exception [" + e.Error.Message + "]", Logger.Level.Error);
            }            

            //Busy indicator.
            BusyIndicator.RemoveBusyTask();
		}

		/// <summary>
		/// GetAdConfigListQuery Callback
		/// </summary>
		/// <param name="e">The result.</param>
		public void OnGetAdConfigListQueryCallback(LoadOperation<AdConfig> e)
		{
			//Variable initialization.
			MessageBoxChildWindow L_oMessage = new MessageBoxChildWindow();

			//All Ad config.
			if (e.HasError)
			{
                //Log Error.
                Logger.Write("GroupAssociationTabViewModel.OnGetAdConfigListQueryCallback Exception [" + e.Error.Message + "]", Logger.Level.Error);

				//User error message.
				L_oMessage = new MessageBoxChildWindow(String.Empty, Resx.GetLabel(ResxRioManagerGroup.GROUP_MSG_CORRESPONDENCE_AD_CONFIG_ERROR), MessageBoxButtons.Ok, MessageBoxIcon.Error);
				L_oMessage.Show();
			}
			else
			{
				//Built the AdConfig list.
				List<AdConfig> l_oAdConfig = new List<AdConfig>(e.Entities);

				if (l_oAdConfig[0].LstAdStructureItem.Count != 0)
				{
					//Fill all AD configuration.
					AdConfigCustomer = new ObservableCollection<AdStructureItem>();
					foreach (AdStructureItem l_oAdStructureItem in l_oAdConfig[0].LstAdStructureItem)
					{
						AdConfigCustomer.Add(l_oAdStructureItem);
					}

                    //Select Ad Mapped on the database.
				    RetrievesAdNameMapped();
				}
				else
				{
					//User message not configuration in the web.config.
					L_oMessage = new MessageBoxChildWindow(String.Empty, Resx.GetLabel(ResxRioManagerGroup.GROUP_MSG_CORRESPONDENCE_AD_NOT_CONFIG), MessageBoxButtons.Ok, MessageBoxIcon.Warning);
					L_oMessage.Show();
				}
			}
		}

		/// <summary>Gets Organization RIO group list.</summary>
		/// <param name="e">Rio Organization group List.</param>
		private void OnGetAllRioOrganizationGroupCallback(LoadOperation<Group> e)
		{
			if (!e.HasError)
			{
				//Built Rio Organization group list.
				SelectedOrganizationRioGroup = null;
				OrganizationRioGroupList = new ObservableCollection<Group>(e.Entities);
			}
            else
            {
                //Log Error.
                Logger.Write("GroupAssociationTabViewModel.OnGetAllRioOrganizationGroupCallback Exception [" + e.Error.Message + "]", Logger.Level.Error);
            }
		}

		/// <summary>Gets RIO group Selected information mapped.</summary>
		/// <param name="e">RIO group Selected information mapped list.</param>
		private void OnGetAdMappedObjectListQueryCallback(LoadOperation<AdObject> e)
		{
			if ((!e.HasError) && (e.Entities != null))
			{
				//Fill Rio group selected information mapped list.
				SelectedAdObjectMapped = null;
				AdObjectMappedList = new ObservableCollection<AdObject>(e.Entities);

                //Check Button Delete.
                CheckButtonAddAndDeleteStatus("Add");

                //Organization and Ad information choice mut to be enabled.
				CanSelectOrganization = false;
				CanSelectAdConfig = false;
			}
            else
            {
                //Log Error.
                Logger.Write("GroupAssociationTabViewModel.OnGetAdMappedObjectListQueryCallback Exception [" + e.Error.Message + "]", Logger.Level.Error);
            }
		}

        /// <summary>Save modification on Rio mapped.</summary>
        /// <param name="e"></param>
        private void OnSubmitChangeCallback(SubmitOperation e)
        {
            if (e.HasError)
            {                
                //Log Error.
                Logger.Write("GroupAssociationTabViewModel.OnGetAdMappedObjectListQueryCallback Exception [" + e.Error.Message + "]", Logger.Level.Error);

                //User error message.
                MessageBox.Show( e.Error.Message.ToString());
                MessageBoxChildWindow L_oMessage = new MessageBoxChildWindow(String.Empty, string.Format(Resx.GetLabel(ResxRioManagerGroup.GROUP_MSG_ASSOCIATION_SAVE_ERROR),((Group)SelectedOrganizationRioGroup[0]).Name), MessageBoxButtons.Ok, MessageBoxIcon.Error);
                L_oMessage.Show();
                e.MarkErrorAsHandled();
            }
            else
            {
                //User sucessfull message.
                MessageBoxChildWindow L_oMessage = new MessageBoxChildWindow(String.Empty, string.Format(Resx.GetLabel(ResxRioManagerGroup.GROUP_MSG_ASSOCIATION_SAVE_SUCCES),((Group)SelectedOrganizationRioGroup[0]).Name), MessageBoxButtons.Ok, MessageBoxIcon.Information);
                L_oMessage.Show();
                L_oMessage.Closed += (s, ev) =>
                {
                    //Deselect the rio group.
                    Messenger.Default.Send<NotificationMessage<ObservableCollection<Group>>>(new NotificationMessage<ObservableCollection<Group>>(OrganizationRioGroupList, String.Empty));

                    //Close button, Organization and Ad information choice mut to be enabled.
                    CanSelectOrganization = true;
                    CanSelectAdConfig = true;
                    CanClose = true;
                };
            }

            //Busy indicator.
            BusyIndicator.RemoveBusyTask();
        }

		#endregion Callback
	}        
}